#ifndef __CONN_PROVIDER_H__
#define __CONN_PROVIDER_H__

//#include "cmimdef.h"
#include "RtReferenceControl.h"
#include "RtMessageBlock.h"
#include "sessbase.h"
#include "RtConnectionInterface.h"
class CRtInetAddr;
class IConnection;
class IConnectionSink;
class IConnProviderSink;

typedef enum
{
	EVENT_TYPE_IM,
	EVENT_TYPE_P2P_PING,
	EVENT_TYPE_CONFERENCE_PING,
	EVENT_TYPE_P2P_SHAREDATA,
	EVENT_TYPE_RUDP,
	EVENT_TYPE_BASIC_TCP,
}Event_Type;

class RT_API_EXPORT IConnProvider
{
public:
	static IConnProvider* Instance();

public:
	virtual RtResult Initialize() = 0;
	virtual RtResult UnInitialize() = 0;
	virtual RtResult Register(Event_Type aType, IConnProviderSink* pSink) =0;

	virtual RtResult Listen(const TransportAddress& aAddress) = 0;
	virtual RtResult AddedListen(const TransportAddress& aAddress) = 0;

	virtual RtResult ListenEx(const TransportAddress& aAddress, Event_Type nType) = 0;
	virtual RtResult AddedListenEx(const TransportAddress& aAddress, Event_Type nType) = 0;

	virtual	RtResult StopListen() = 0;
	
	virtual RtResult GetListenAddress(BOOL aPrimary, TransportAddress& aAddress) = 0;

	virtual RtResult Connect(IConnProviderSink* pSink,
							 DWORD aNumber,
							 const TransportAddress* aAddresses,
							 Event_Type aEventType = EVENT_TYPE_IM,
							 CRtTimeValue *aTimeout = NULL,
							 BOOL aSync = FALSE) = 0;
	virtual RtResult ConnectData(
							 IConnProviderSink* pSink, 
							 DWORD aNumber,
							 TransportAddress* aAddresses,
							 Event_Type aEventType = EVENT_TYPE_CONFERENCE_PING) =0;

	virtual RtResult CancelConnect(
							 IConnProviderSink* pSink, 
							 TransportAddress* aAddress = NULL,
							 BOOL aHaveMultiPort = FALSE) = 0;

protected:
	virtual ~IConnProvider() {}
};

class RT_API_EXPORT IConnProviderSink
{
public:
	virtual void OnConnectionReady(
							 RtResult aResult,
							 IConnection* pConn, // pAddr!=NULL if getten by connector; pAddr==NULL if getten by acceptor
							 const CRtInetAddr* pAddr) = 0;

protected:
	virtual ~IConnProviderSink() {}
};

class RT_API_EXPORT IConnection: public IRtReferenceControl
{
public:
	virtual RtResult Initialize(IConnectionSink* pSink) = 0;
	virtual RtResult SendData(CRtMessageBlock& aData,
							  BOOL aSendImmediately = TRUE,
							  RtRudpReliability aReliability = RUDP_RELIABLE_ORDERED,
							  IRtTransport::RudpChannel aChannelID = 0,
							  INT aTTL = -1) = 0;
	virtual RtResult Disconnect(RtResult aReason) = 0;
	virtual RtResult GetOption(DWORD aOption, LPVOID lpData) = 0;
	virtual RtResult SetOption(DWORD aOption, LPVOID lpData) = 0;

protected:
	virtual ~IConnection() {}
};

class RT_API_EXPORT IConnectionSink
{
public:
	virtual void OnReceiveData(CRtMessageBlock& aData, IConnection* pConn) = 0;
	virtual void OnDisconnect(RtResult aReason, IConnection* pConn) = 0; 
	virtual void OnSend(IConnection* pConn) = 0;

protected:
	virtual ~IConnectionSink() {}
};

#endif //!__CONN_PROVIDER_H__

